/**
 * 实现一个retry函数，对可能失败的异步操作进行自动重试
 */

/**
 * 异步重试机制
 * @param {Function} fn - 要执行的异步函数，返回 Promise
 * @param {Object} options - 配置选项
 * @param {number} options.maxRetries - 最大重试次数（不包括第一次尝试）
 * @param {number} options.delay - 重试延迟时间(ms)
 * @param {Function} options.shouldRetry - 判断是否应该重试的函数 (error) => boolean
 * @param {Function} options.onRetry - 重试时的回调函数 (error, attempt) => void
 * @returns {Promise} - 返回最终的 Promise
 */
function retry(fn, options) {
    const {
        maxRetries = 3,
        delay = 1000,
        shouldRetry = () => true,
        onRetry = () => {},
        backoff = 1
    } = options || {};
 
    return new Promise((resolve, reject) => {
        const execute = async (attempt = 0) => {
            try{
                const result = await fn();
                resolve(result);
            }catch(error) {
                const isLastAttempt = attempt >= maxRetries;
                const canRetry = shouldRetry(error) && !isLastAttempt;
                if (!canRetry) {
                    reject(error);
                    return;
                }

                const currentDelay = delay * Math.pow(backoff, attempt);
                onRetry(error, attempt + 1);

                setTimeout(() => {
                    execute(attempt + 1);
                }, currentDelay);
            }
        };

        execute(0);
    });
}




// 基本用法
const result1 = await retry(fetchData, {
  maxRetries: 3,
  delay: 1000
});

// 高级用法：只在特定错误时重试
const result2 = await retry(unstableAPI, {
  maxRetries: 5,
  delay: 2000,
  shouldRetry: (error) => error.statusCode === 503, // 只在503错误时重试
  onRetry: (error, attempt) => {
    console.log(`第${attempt}次重试，错误: ${error.message}`);
  }
});